<?php

/**
 * 数据的加密,解密
 *
 * @author tommy <tommy@doitphp.com>
 * @copyright Copyright (c) 2010 Tommycode Studio, ColaPHP
 * @link http://www.doitphp.com
 * @license New BSD License.{@link http://www.opensource.org/licenses/bsd-license.php}
 * @version $Id: Encrypt.php 2.0 2012-12-29 16:20:14Z tommy $
 * @package library
 * @since 1.0
 */

class Encrypt {

    /**
     * config data
     *
     * @var array
     */
    protected $_config = array();

    /**
     * 加密字符串(密钥)
     *
     * @var string
     */
    protected static $_key = 'your-secret-code';

    /**
     * 构造方法
     *
     * @access public
     * @return boolean
     */
    public function __construct() {

        //set config infomation
//        $this->_config = array(
//            'hash' => 'sha1',
//            'xor' => false,
//            'mcrypt' => function_exists('mcrypt_encrypt') ? true : false,
//            'noise' => true,
//            'cipher' => MCRYPT_RIJNDAEL_256,
//            'mode' => MCRYPT_MODE_ECB
//        );

        return true;
    }

    /**
     * 设置或获取配置参数($_config)信息
     *
     * @access public
     *
     * @param mixed $key 键值
     * @param mixed $value 参数值
     *
     * @return mixed
     */
    public function config($key = null, $value = null) {

        if (is_null($key)) {
            return $this->_config;
        }

        if (is_array($key)) {
            $this->_config = $key + $this->_config;
            return $this;
        }

        if (is_null($value)) {
            return $this->_config[$key];
        }

        $this->_config[$key] = $value;

        return $this;
    }

    /**
     * 加密
     *
     * @access public
     *
     * @param string $string 待加密的字符串
     * @param string $key 密钥
     *
     * @return string
     */
    public function encode($string, $key = null) {

        if (is_null($key)) {
            $key = self::$_key;
        }

//        if ($this->_config['xor']) {
//            $string = $this->_xorEncode($string, $key);
//        }
//
//        if ($this->_config['mcrypt']) {
//            $string = $this->_mcryptEncode($string, $key);
//        }
//
//        if ($this->_config['noise']) {
//            $string = $this->_noise($string, $key);
//        }
        return $this->encrypt($string, 'E', $key);

        return base64_encode($string);
    }

    /**
     * 解密
     *
     * @access public
     *
     * @param string $string 待解密的字符串
     * @param string $key 附加码
     *
     * @return string
     */
    public function decode($string, $key = null) {

        if (is_null($key)) {
            $key = self::$_key;
        }
//
//        if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string)) {
//            return false;
//        }
//
//        $string = base64_decode($string);
//
//        if ($this->_config['noise']) {
//            $string = $this->_denoise($string, $key);
//        }
//
//        if ($this->_config['mcrypt']) {
//            $string = $this->_mcryptDecode($string, $key);
//        }
//
//        if ($this->_config['xor']) {
//            $string = $this->_xorDecode($string, $key);
//        }
        return $this->encrypt($string, 'D', $key);

        return $string;
    }

    /**
     * Mcrypt encode
     *
     * @access protected
     *
     * @param string $string 待加密的字符串
     * @param string $key 附加码
     *
     * @return string
     */
    protected function _mcryptEncode($string, $key) {

        $cipher = $this->_config['cipher'];
        $mode = $this->_config['mode'];
        $size = mcrypt_get_iv_size($cipher, $mode);
        $vect = mcrypt_create_iv($size, MCRYPT_RAND);

        return mcrypt_encrypt($cipher, $key, $string, $mode, $vect);
    }

    public function encrypt($string, $operation, $key = '') {
        $key = md5($key);
        $key_length = strlen($key);
        $string = $operation == 'D' ? $this->base_decode($string) : substr(md5($string . $key), 0, 8) . $string;
        $string_length = strlen($string);
        $rndkey = $box = array();
        $result = '';
        for ($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($key[$i % $key_length]);
            $box[$i] = $i;
        }
        for ($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
        for ($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
        }
        if ($operation == 'D') {
            if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) {
                return substr($result, 8);
            } else {
                return'';
            }
        } else {
            return $this->base_encode($result);
        }
    }

    /**
     * 生成随机码
     *
     * @access public
     *
     * @param integer $length 随机码长度 (0~32)
     *
     * @return string
     */
    public static function randCode($length = 5) {

        //参数分析
        $length = (int) $length;
        $length = ($length > 32) ? 32 : $length;

        $code = md5(uniqid(mt_rand(), true));
        $start = mt_rand(0, 32 - $length);

        return substr($code, $start, $length);
    }
    
    function base_encode($str) {
        $src  = array("/","+","=");
        $dist = array("_a","_b","_c");
        $old  = base64_encode($str);
        $new  = str_replace($src,$dist,$old);
        return $new;
}
 
    function base_decode($str) {
            $src = array("_a","_b","_c");
            $dist  = array("/","+","=");
            $old  = str_replace($src,$dist,$str);
            $new = base64_decode($old);
            return $new;
    }

}
